package com.sxhuayuan.parking.socket;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;

/**
 * 同步返回结果
 * 
 * @author gy
 */
public class SyncFuture<T> implements Future<T> {

	private String uid;
	// 因为请求和响应是一一对应的，因此初始化CountDownLatch值为1。
	private CountDownLatch latch = new CountDownLatch(1);
	// 需要响应线程设置的响应结果
	private T response = null;
	// Futrue的请求时间，用于计算Future是否超时
	private long beginTime = System.currentTimeMillis();

	// private List<GenericFutureListener<? extends Future<? super T>>>
	// listenersList = new ArrayList<>();

	private Throwable throwable;

	public SyncFuture(String uid) {
		this.setUid(uid);
	}

	@Override
	public boolean isCancelled() {
		return false;
	}

	@Override
	public boolean isDone() {
		return response != null;
	}

	@Override
	public T get() throws InterruptedException, ExecutionException {
		latch.await();
		return this.response;
	}

	@Override
	public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
		if (latch.await(timeout, unit)) {
			return this.response;
		}
		return null;
	}

	@Override
	public boolean isSuccess() {
		return response != null;
	}

	@Override
	public boolean isCancellable() {
		return false;
	}

	@Override
	public Throwable cause() {
		return throwable;
	}

	@Override
	public Future<T> addListener(GenericFutureListener<? extends Future<? super T>> listener) {
		// listenersList.add(listener);
		return this;
	}

	@Override
	public Future<T> addListeners(GenericFutureListener<? extends Future<? super T>>... listeners) {
		// this.listenersList.addAll(java.util.Arrays.asList(listeners));
		return this;
	}

	@Override
	public Future<T> removeListener(GenericFutureListener<? extends Future<? super T>> listener) {
		// listenersList.remove(listener);
		return this;
	}

	@Override
	public Future<T> removeListeners(GenericFutureListener<? extends Future<? super T>>... listeners) {
		// this.listenersList.removeAll(java.util.Arrays.asList(listeners));
		return this;
	}

	@Override
	public Future<T> sync() throws InterruptedException {
		latch.await();
		return this;
	}

	@Override
	public Future<T> syncUninterruptibly() {
		try {
			latch.await();
		} catch (InterruptedException e) {
		}
		return this;
	}

	@Override
	public Future<T> await() throws InterruptedException {
		latch.await();
		return this;
	}

	@Override
	public Future<T> awaitUninterruptibly() {
		try {
			latch.await();
		} catch (InterruptedException e) {
		}
		return this;
	}

	@Override
	public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
		return latch.await(timeout, unit);
	}

	@Override
	public boolean await(long timeoutMillis) throws InterruptedException {
		return latch.await(timeoutMillis, TimeUnit.MILLISECONDS);
	}

	@Override
	public boolean awaitUninterruptibly(long timeout, TimeUnit unit) {
		try {
			latch.await(timeout, unit);
			return true;
		} catch (InterruptedException e) {
			return false;
		}
	}

	@Override
	public boolean awaitUninterruptibly(long timeoutMillis) {
		try {
			latch.await(timeoutMillis, TimeUnit.MILLISECONDS);
			return true;
		} catch (InterruptedException e) {
			return false;
		}
	}

	@Override
	public T getNow() {
		return response;
	}

	@Override
	public boolean cancel(boolean mayInterruptIfRunning) {
		return false;
	}

	public long getBeginTime() {
		return beginTime;
	}

	public void setThrowable(Throwable throwable) {
		this.throwable = throwable;
	}

	public String getUid() {
		return uid;
	}

	public void setUid(String uid) {
		this.uid = uid;
	}

	public void setResponse(T response) {
		this.response = response;
		latch.countDown();
	}

}
